<?php


namespace Base;


use App\Exceptions\DangerousDbAction;
use Exception;
use Lib\DB;
use Medoo\Medoo;

class BaseModel
{
    /**
     * 表名
     * @var null | string
     */
    protected $table = null;

    /**
     * @var null | Medoo
     */
    private $db = null;

    public function __construct($db = null)
    {
        if ($this->table === null) {
            $class = explode('\\', get_class($this));
            $this->table = strtolower(str_replace('Model', '', $class[count($class) - 1]));
        }
        if ($db !== null) {
            $this->db = $db;
        } else {
            $this->db = DB::init();
        }
    }

    /**
     * 插入
     * @param $data
     * @return int
     */
    protected function baseInsert($data)
    {
        $this->db->insert(
            $this->table,
            $data
        );
        return $this->db->id();
    }

    /**
     * 删除
     * @param array $where
     * @return int
     * @throws DangerousDbAction
     */
    protected function baseDelete($where = [])
    {
        if (empty($where)) {
            throw new DangerousDbAction("未设置删除条件");
        }
        return $this->db->delete(
            $this->table,
            $where
        )->rowCount();
    }

    /**
     * 更新
     * @param array $where
     * @param array $data
     * @return int
     */
    protected function baseUpdate($where = [], $data = [])
    {
        return $this->db->update(
            $this->table,
            $data,
            $where
        )->rowCount();
    }

    /**
     * 查询
     * @param array $where
     * @param array $fields
     * @return mixed
     */
    protected function baseSelect($fields, $where)
    {
        return $this->db->select($this->table, $fields, $where) ?: [];
    }

    protected function baseSelectFirst($fields = [], $where = [])
    {
        return $this->db->get(
            $this->table,
            $fields,
            $where
        ) ?: [];
    }

    /**
     * 查询数量
     * @param array $where
     * @return int
     */
    protected function baseSelectCount($where = [])
    {
        return $this->db->count(
            $this->table,
            $where
        ) ?: 0;
    }

    /**
     * 按分页查询
     * @param array $where
     * @param array $fields
     * @param int $limit
     * @param int $page
     * @return array
     */
    protected function baseSelectByPage($where = [], $fields = '*', $limit = 20, $page = 1)
    {
        $where["LIMIT"] = [($page - 1) * $limit, $limit];
        return $this->db->select(
            $this->table,
            $fields,
            $where
        ) ?: [];
    }

    /**
     * 自增
     * @param array $where
     * @param string $column
     * @param int $step
     * @return int
     */
    protected function baseInc($where = [], $column = '', $step = 1)
    {
        return $this->db->update(
            $this->table,
            [
                "{$column}[+]" => $step
            ],
            $where
        )->rowCount();
    }

    /**
     * 自减
     * @param array $where
     * @param string $column
     * @param int $step
     * @return int
     */
    protected function baseDec($where = [], $column = '', $step = 1)
    {
        return $this->db->update(
            $this->table,
            [
                "{$column}[-]" => $step
            ],
            $where
        )->rowCount();
    }

    /**
     * 事务
     * @param $queryColure
     * @throws Exception
     */
    public function baseTransaction(\Closure $queryColure, $params = [])
    {
        $this->db->action($queryColure($this->db, $params));
    }

    /**
     * 创建索引数组
     * @param array $idArr
     * @param string $idColumnName
     * @param string $arrKey
     * @param string $fields
     * @param array $extraWhere
     * @return array
     */
    protected function baseCreateDictionary($idArr = [], $idColumnName = 'id', $arrKey = 'id', $fields = '*', $extraWhere = [])
    {
        if (!$idArr) {
            return [];
        }
        $whereArr = [
            $idColumnName => $idArr
        ];
        if (!empty($extraWhere)) {
            $whereArr = array_merge($whereArr, $extraWhere);
        }
        $data = $this->db->select(
            $this->table,
            $fields,
            $whereArr
        );

        if (!empty($data)) {
            return array_column($data, null, $arrKey);
        } else {
            return [];
        }
    }

    /**
     * 创建分组索引数组
     * @param array $idArr
     * @param string $idColumnName
     * @param string $arrKey
     * @param array $fields
     * @param array $extraWhere
     * @return array
     */
    protected function baseCreateGroupDictionary($idArr = [], $idColumnName = 'id', $arrKey = 'id', $fields = "*", $extraWhere = [])
    {
        if (!$idArr) {
            return [];
        }
        $whereArr = [
            $idColumnName => $idArr
        ];
        if (!empty($extraWhere)) {
            $whereArr = array_merge($whereArr, $extraWhere);
        }
        $data = $this->db->select(
            $this->table,
            $fields,
            $whereArr
        );

        if (!empty($data)) {
            $resArr = [];
            foreach ($data as $k => $v) {
                $resArr[$v[$arrKey]][] = $v;
            }
            return $resArr;
        } else {
            return [];
        }
    }
}
